package com.funcablaze.component.Scene;

import com.funcablaze.Application;
import com.funcablaze.component.control.Graphic;
import com.funcablaze.component.control.Theme;
import com.funcablaze.component.view.View;
import com.funcablaze.func.parser.XML;
import com.funcablaze.window.BaseWindow;
import com.funcablaze.window.Frame;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL30;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;

public abstract class Scene {
	protected BaseWindow window;
	protected View rootView;
	protected Graphic graphic;
	
	/**
	 * 从XML文件中加载场景
	 * @param name XML文件名
	 * @return 场景
	 */
	public static Scene inflate(String name) throws IOException, ClassNotFoundException, ParserConfigurationException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, SAXException {
		InputStream is = View.class.getResourceAsStream(name);
		return XML.SceneParser.parser(is);
	}
	
	/**
	 * 渲染场景
	 */
	public boolean draw(Theme.ThemeType theme) {
		if (window == null) throw new IllegalStateException("场景未绑定窗口。");
		if (window.isVisible()) {
			// 清屏
			GL30.glClearColor(
					Application.GlobalStyle.backgroundColor.r(),
					Application.GlobalStyle.backgroundColor.g(),
					Application.GlobalStyle.backgroundColor.b(),
					Application.GlobalStyle.backgroundColor.a()
			);
			GL30.glClear(GL30.GL_COLOR_BUFFER_BIT);
			// 渲染视图树
			rootView.draw(graphic, theme);
			// 交换缓冲
			GLFW.glfwSwapBuffers(window.getWindowHandle());
			GLFW.glfwPollEvents();
			return true;
		}
		return false;
	}
	
	/**
	 * 绑定窗口
	 */
	public void bindWindow(BaseWindow baseWindow) {
		this.window = baseWindow;
	}
	
	/**
	 * 获取根视图
	 * @return 根视图
	 */
	public View getRootView() {
		return rootView;
	}
	
	/**
	 * 设置根视图
	 * @param rootView 根视图
	 */
	public void setRootView(View rootView) {
		this.rootView = rootView;
	}
	
	/**
	 * 设置渲染器
	 * @param graphic 渲染器
	 */
	public void setGraphic(Graphic graphic) {
		this.graphic = graphic;
	}
}
